<?php

/**
 * 用户模型
 *
 * @author JiangJian <silverd@sohu.com>
 * $Id: User.php 143 2012-10-22 02:18:09Z silverd30@gmail.com $
 */

class Model_User extends Core_Model_Abstract implements ArrayAccess
{
    const
        STATUS_IN_PORT = 0, // 港口中
        STATUS_SAILING = 1; // 航行中

    /**
     * 当前用户信息
     *
     * @var array
     */
    protected $_user = array();

    public function __construct($uid)
    {
        // 基本信息
        $user = Dao('User_Info')->loadDs($uid)->get($uid);
        if (!$user) {
            throw new Core_Exception_Logic('用户信息不存在');
        }

        // 等级信息
        $user['level'] = Dao('Static_Level')->get($user['level_id']);
        $user['next_level'] = Dao('Static_Level')->get($user['level_id'] + 1);

        // 官职信息
        if ($user['position_id']) {
            $user['position'] = Dao('Static_Position')->get($user['position_id']);
        }

        // 国家信息
        if ($user['country_id']) {
            $user['country'] = Dao('Static_Country')->get($user['country_id']);
        }

        $this->_user = $user;
    }

    public function offsetSet($key, $value)
    {
        $this->_user[$key] = $value;
    }

    public function offsetExists($key)
    {
        return isset($this->_user[$key]);
    }

    public function offsetUnset($key)
    {
        unset($this->_user[$key]);
    }

    public function offsetGet($key)
    {
        return isset($this->_user[$key]) ? $this->_user[$key] : null;
    }

    public function __toString()
    {
        return print_r($this->_user, true);
    }

    public function __toArray()
    {
        return $this->_user;
    }

    /**
     * 升级
     *
     * @return bool
     */
    public function levelUp()
    {
        // 已经是最大等级（没有下一级了）
        if (!$this->_user['next_level']) {
            return false;
        }

        // 经验值还未到下一级别的升级线
        if (!$this->_user['exp'] < $this->_user['next_level']['exp']) {
            return false;
        }

        $curLevel = Dao('Static_Level')->getLevelByExp($this->_user['exp']);
        if ($curLevel['level_id'] == $this->_user['level_id'])  {
            return false;
        }

        // 更新字段
        return $this->update('level_id', $curLevel['level_id']);
    }

    /**
     * 消耗金块
     *
     * @param int $num
     * @return bool
     */
    public function consumeGold($num)
    {

    }

    /**
     * 消耗银币
     *
     * @param int $num
     * @return bool
     */
    public function consumeSilver($num)
    {

    }

    /**
     * 更新用户（封装）
     *
     * @param string/array $key
     * @param mixed/null $value
     * @return void
     */
    public function update($key, $value = null)
    {
        $setArr = $key;
        if (!is_array($key)) {
            $setArr = array($key => $value);
        }

        // 更新用户索引表
        $this->_updateUserIndex($setArr);

        // 更新用户详细信息表
        $this->_updateUserInfo($setArr);
    }

    /**
     * 更新用户索引表
     *
     * @param array &$setArr
     * @return void
     */
    protected function _updateUserIndex(&$setArr)
    {
        $setArrIndex = array();

        foreach (array('level_id', 'postion_id', 'country_id', 'user_name') as $field) {
            if (isset($setArr[$field])) {
                $setArrIndex[$field] = $setArr[$field];
                unset($setArr[$field]);
            }
        }

        if ($setArrIndex) {
            Dao('User_Index')->updateByPk($setArrIndex, $this->_user['uid']);
        }
    }

    /**
     * 更新用户详细信息表
     *
     * @param array &$setArr
     * @return bool
     */
    protected function _updateUserInfo(&$setArr)
    {
        return Dao('User_Info')->loadDs($this->_user['uid'])->updateByPk($setArr, $this->_user['uid']);
    }

    /**
     * 增加航行记录
     *
     * @param int $portTo
     * @param bool $isInstant 是否瞬间移动
     * @return bool
     */
    public function sailLog($portTo, $isInstant = 0)
    {
        $setArr = array(
            'uid'         => $this->_user['uid'],
            'port_from'   => $this->_user['port_from'],
            'port_to'     => $portTo,
            'depart_time' => $GLOBALS['_TIME'],
            'arrive_time' => $GLOBALS['_TIME'],
            'is_instant'  => $isInstant ? 1 : 0,
        );

        return Dao('User_SailLog')->loadDs($this->_user['uid'])->insert($setArr);
    }

    /**
     * 扬帆起航
     *
     * @param int $portTo
     * @return bool
     */
    public function sailDepart($portTo)
    {
        // 两个港口间需要航行多久(单位:秒)
        $distanceTime = Dao('Static_Port')->getDistance($this->_user['port_from'], $portTo);

        // 更新玩家目标港口、出港时间、到达时间
        $setArr = array(
            'port_to'     => $portTo,
            'depart_time' => $GLOBALS['_TIME'],
            'arrive_time' => $GLOBALS['_TIME'] + $distanceTime,
            'status'      => 1,  // 更新状态：航行中
        );

        return $this->update($setArr);
    }

    /**
     * 到达目标港口
     *
     * @return bool
     */
    public function sailArrive()
    {
        $setArr = array(
            'port_from'   => $this->_user['port_to'],
            'port_to'     => 0,
            'depart_time' => 0,
            'arrive_time' => 0,
            'status'      => 0,  // 更新状态：港口停泊中
        );

        return $this->update($setArr);
    }

    /**
     * 加载我的舰船信息
     *
     * @return array
     */
    public function getShipList()
    {
        $shipList = Dao('User_Ship')->loadDs($this->_user['uid'])->find(array('uid' => $this->_user['uid']));

        // demo
        $shipList = array(
            array('ship_id' => 1, 'captain_id' => 11),
            array('ship_id' => 2, 'captain_id' => 22),
            array('ship_id' => 3, 'captain_id' => 33),
            array('ship_id' => 4, 'captain_id' => 44),
            array('ship_id' => 5, 'captain_id' => 55),
        );

        foreach ($shipList as $key => &$ship) {
            if ($shipInfo = Dao('Static_Ship')->get($ship['ship_id'])) {
                $ship += $shipInfo;
            } else {
                unset($shipList[$key]);
            }
        }

        return $shipList;
    }

    /**
     * 海战对手列表
     *
     * @return array
     */
    public function getFightOpponent()
    {
/*
   在同一海域内
   度过新手教程，等级高于20级（暂定）
   等级差不超过+5级
   不处于同一国家
   可以直接攻击在同一海域内的悬赏榜上的异国玩家，无等级限制
   拥有至少一场战斗的精力消耗数量
   足够的体力，具体数值待定
 */

        // 等级范围
        $levelStart = max(1, $this->_user['level_id'] - 5);
        $levelEnd   = $this->_user['level_id'] + 5;

        // demo
        $whereSql = '1';
        $whereSql .= " AND level_id >= '{$levelStart}' AND level_id <= '{$levelEnd}'";
        $whereSql .= " AND uid != '{$this->_user['uid']}'";
        $whereSql .= " AND country_id != '{$this->_user['country_id']}'";
        // $whereSql .= " AND status = 1";
        // $whereSql .= " AND hp >= '". Model_Fight::USER_MIN_HP . "'";

        $list = Dao('User_Index')->findByPage($whereSql, 0, 10);
        if (!$list) {
            return array();
        }

        // TODO 计算战斗力、公会信息
        foreach ($list as &$value) {
            $value['flagship_id'] = rand(1, 5); // demo
        }

        return $list;
    }
}